package com.coconet.gas.until;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.net.telnet.TelnetClient;
import org.joda.time.DateTime;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.util.StringUtils;

import com.coconet.gas.constant.RotdrCommond;
import com.coconet.gas.constant.dwEnum;
import com.coconet.gas.exception.ServiceException;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.SftpException;

/**
 * Telnet操作器,基于commons-net-2.2.jar
 * 
 * @author JiangKunpeng
 *
 */
public class TelnetUtil {

	private String prompt = "\r\n"; // 结束标识字符串,Windows中是>,Linux中是#
	private char promptChar = '>'; // 结束标识字符
	private TelnetClient telnet;
	private InputStream in; // 输入流,接收返回信息
	private PrintStream out; // 向服务器写入 命令
	private String suffixinstruction = "\r\n";

	/**
	 * @param termtype
	 *            协议类型：VT100、VT52、VT220、VTNT、ANSI
	 * @param prompt
	 *            结果结束标识
	 */
	public TelnetUtil(String termtype, String prompt) {
		telnet = new TelnetClient(termtype);
		setPrompt(prompt);
	}

	public TelnetUtil(String termtype) {
		telnet = new TelnetClient(termtype);
	}

	public TelnetUtil() {
		telnet = new TelnetClient();
	}

	public void test(String ip, int port, int time) throws SocketException, IOException {

		telnet.setConnectTimeout(time);
		telnet.connect(ip, port);

		in = telnet.getInputStream();
		out = new PrintStream(telnet.getOutputStream());

		telnet.disconnect();

	}

	public String conhj(String ip, int port, String prompt, int time, String ch) {
		String str = null;
		try {
			telnet.setConnectTimeout(time);
			telnet.connect(ip, port);
			// Thread.sleep(1000);
			// telnet.connect(ip, port);

			in = telnet.getInputStream();
			out = new PrintStream(telnet.getOutputStream());
			// str =sendCommand(ch);

		} catch (Exception e) {
			str = null;
		}
		return str;
	}

	public void con(String ip, int port) {

		try {
			telnet.connect(ip, port);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		in = telnet.getInputStream();
		out = new PrintStream(telnet.getOutputStream());

	}

	public InputStream getIn() {
		return in;
	}

	public void setIn(InputStream in) {
		this.in = in;
	}

	public PrintStream getOut() {
		return out;
	}

	public void setOut(PrintStream out) {
		this.out = out;
	}

	public String connect(String ip, int port, String prompt, int time, String ch) throws SocketException, IOException {
		String str = null;

		telnet.setConnectTimeout(time);
		telnet.connect(ip, port);

		in = telnet.getInputStream();
		out = new PrintStream(telnet.getOutputStream());
		str = sendCommand(ch);
		telnet.disconnect();

		return str;
	}

	public String connectpower(String ip, int port, String prompt, int time, String ch)
			throws SocketException, IOException {
		String str = null;
		telnet.setConnectTimeout(time);
		telnet.connect(ip, port);
		telnet.setSoTimeout(100000);
		in = telnet.getInputStream();
		out = new PrintStream(telnet.getOutputStream());
		str = sendCommand(ch, prompt);
		telnet.disconnect();
		System.err.println(str);
		if (str.contains("ERR20") || str.contains("ERR40") || str.subSequence(0, 1).equals("4")||str.contains("error")||str.subSequence(0, 1).equals("1") ) {
			throw new ServiceException(dwEnum.FAILURE.code(), "命令执行错误请检查硬件，错误代码->"+str);
		}
		return str;
	}

	public void sendCh(String ip, int port, String prompt, int time, String ch) throws SocketException, IOException {
		telnet.setConnectTimeout(time);
		telnet.connect(ip, port);

		in = telnet.getInputStream();
		out = new PrintStream(telnet.getOutputStream());
		write(ch);
		telnet.disconnect();

	}

	public void sendCh(String ip, int port, String prompt, int time, byte[] ch) throws SocketException, IOException {
		telnet.setConnectTimeout(time);
		telnet.connect(ip, port);

		in = telnet.getInputStream();
		out = new PrintStream(telnet.getOutputStream());
		write(ch);
		telnet.disconnect();

	}

	/**
	 * 登录到目标主机
	 * 
	 * @param ip
	 * @param port
	 * @param username
	 * @param password
	 */
	public void login(String ip, int port, String username, String password) {
		try {
			telnet.connect(ip, port);
			in = telnet.getInputStream();
			out = new PrintStream(telnet.getOutputStream());
			readUntil("login:");
			write(username);
			readUntil("password:");
			write(password);
			String rs = readUntil(null);
			if (rs != null && rs.contains("Login Failed")) {
				throw new RuntimeException("登录失败");
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 读取分析结果
	 * 
	 * @param pattern
	 *            匹配到该字符串时返回结果
	 * @return
	 */
	public String readUntil(String pattern) {
		StringBuffer sb = new StringBuffer();
		try {
			char lastChar = (char) -1;
			boolean flag = pattern != null && pattern.length() > 0;
			if (flag)
				lastChar = pattern.charAt(pattern.length() - 1);
			char ch;
			int code = -1;
			while ((code = in.read()) != -1) {
				ch = (char) code;
				sb.append(ch);

				// 匹配到结束标识时返回结果
				if (flag) {
					if (ch == lastChar && sb.toString().endsWith(pattern)) {
						return sb.toString();
					}
				} else {
					// 如果没指定结束标识,匹配到默认结束标识字符时返回结果
					if (ch == promptChar)
						return sb.toString();
				}
				// 登录失败时返回结果
				if (sb.toString().contains("Login Failed")) {
					return sb.toString();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sb.toString();
	}

	/**
	 * 读取分析结果
	 * 
	 * @param pattern
	 *            匹配到该字符串时返回结果
	 * @return
	 */
	public String readUntil(String[] patterns, String[] rexs) {
		StringBuffer sb = new StringBuffer();

		try {
			// String str = null;
			// while((str = bufferedReader.readLine())!=null){
			// sb.append(str);
			// if(checkPatAndRex(str,patterns,rexs)){
			// return sb.toString();
			// }
			// }
			//
			int code = -1;
			while ((code = in.read()) != -1) {
				char ch = (char) code;
				sb.append(ch);

				String[] strs = sb.toString().replace("\r", "").split("\n");
				for (String str : strs) {
					if (checkPatAndRex(str.toLowerCase(), patterns, rexs)) {
						return sb.toString();
					}
				}

				// System.out.println(sb.toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sb.toString();
	}

	private boolean checkPatAndRex(String str, String[] pats, String[] rexs) {
		if (str == null) {
			return false;
		}
		if (pats == null && rexs == null) {
			return false;
		}
		if (str.length() == 0) {
			return false;
		}
		if (pats != null) {
			for (String pat : pats) {
				if (str.equalsIgnoreCase(pat.toLowerCase())) {
					return true;
				}
			}
		}
		if (rexs != null) {
			for (String rex : rexs) {
				if (str.matches(rex)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 发送命令
	 * 
	 * @param value
	 */
	public void write(String value) {
		try {

			out.println(value);
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void write(byte[] value) {
		try {

			out.println(value);
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 发送命令,返回执行结果
	 * 
	 * @param command
	 * @return
	 */
	public String sendCommand(String command) {
		try {
			write(command);
			return readUntil(prompt);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 发送命令,返回执行结果
	 * 
	 * @param command
	 * @return
	 */
	public String sendCommand(String command, String prompt) {
		try {
			write(command);
			return readUntil(prompt);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 发送命令,返回执行结果
	 * 
	 * @param command
	 * @return
	 */
	public String sendCommand(String command, String[] prompts, String[] regs) {
		try {
			write(command);
			return readUntil(prompts, regs);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 关闭连接
	 */
	public void distinct() {
		try {
			if (telnet != null && !telnet.isConnected())
				out.close();
			in.close();
			telnet.disconnect();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void setPrompt(String prompt) {
		if (prompt != null) {
			this.prompt = prompt;
			this.promptChar = prompt.charAt(prompt.length() - 1);
		}
	}

	public static void main(String[] args) {
		TelnetUtil telnet = new TelnetUtil();
		try {
			//
			// String str = telnet.connectpower("192.168.8.101", 6666, "\r\n", 5000,
			// "init");
			// System.out.print(str);

			// str = telnet.connectpower("192.168.8.101", 6666, "\r\n", 5000,
			// RotdrCommond.statux.getDesc()+"\r\n");
			// System.out.print("state"+str);
			//
			// if (!StringUtils.isEmpty(str)) {
			// str = str.replaceAll("<", "");
			// str = str.replaceAll(">", "");
			// if (str.indexOf("STATE 0") > -1) {
			// }else {
			// str = telnet.connectpower("192.168.8.101", 6666, "\r\n", 5000,
			// RotdrCommond.SCAN.getDesc());
			//
			// }
			// }
			String osw = RotdrCommond.OSW.getDesc() + 1;
			String str = telnet.connectpower("192.168.0.167", 23, "\r\n", 5000, osw);
			System.out.print(str);

			String mp = RotdrCommond.PulsewidthFrequency.getDesc() + 10 + " " + 2000;
			str = telnet.connectpower("192.168.8.101", 6666, "\r\n", 5000, mp);
			System.out.print(str);

			// String curr = RotdrCommond.CURRENT.getDesc() + 110;
			// str = telnet.connectpower("192.168.8.101", 6666, "\r\n", 5000, curr);
			// System.out.print(str);

			String re = RotdrCommond.refractive.getDesc() + "1.465";
			str = telnet.connectpower("192.168.8.101", 6666, "\r\n", 5000, re);
			System.out.print(str);

			// 设置 acqt com3.4
			String ac = RotdrCommond.ACQT.getDesc() + 15;
			str = telnet.connectpower("192.168.8.101", 6666, "\r\n", 5000, ac);
			System.out.print(str);

			str = telnet.connectpower("192.168.8.101", 6666, "\r\n", 5000, RotdrCommond.SCAN.getDesc());
			System.out.print("开始scan了->>>>" + str);

			while (true) {
				str = telnet.connectpower("192.168.8.101", 6666, "\r\n", 5000, RotdrCommond.statux.getDesc());
				// System.out.print("state"+str);
				if (!StringUtils.isEmpty(str)) {
					str = str.replaceAll("<", "");
					str = str.replaceAll(">", "");
					if (str.indexOf("STATE 0") > -1) {
						break;
					}
				}
				try {
					Thread.sleep(10000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			if (str.contains("STATE 0")) {
				str = telnet.connectpower("192.168.8.101", 6666, "\r\n", 5000, RotdrCommond.GETTHEXFILE.getDesc());
				System.out.print(str);
				str = telnet.connectpower("192.168.8.101", 6666, "\r\n", 5000, RotdrCommond.GETTEMPERATURE.getDesc());
				System.out.print(str);

				//System.out.println(telnet.getFile());
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public Map<String, Object> getFile(String ip) {

		List<String> itemList = new ArrayList<String>();
		Map<String, Object> map = new HashMap<>();
		SSHBase sb = null;
		sb = new SSHBase(ip, "IFMS", "123456", 22);
		try {
			sb.connect();
			ChannelSftp sftp = null;
			sftp = (ChannelSftp) sb.getSession().openChannel("sftp");
			sftp.connect();
			//System.out.println(sftp.pwd());
			//sftp.cd("../../otdr-exe/ram/disk/");
			//System.out.println(sftp.pwd());
			//
			DateTime today = new DateTime();
			String time = today.toString("yyyy-MM-dd HH:mm:ss").replaceAll("-", "_").replaceAll(" ", "_")
					.replaceAll(":", "_");
			ApplicationHome h = new ApplicationHome(getClass());
			File jarF = h.getSource();
			String path ;
			if (jarF==null) {
				 path = h.toString() + "\\ROTDR\\" + time + "\\";

			}else {
				 path = jarF.getParentFile() + "\\ROTDR\\" + time + "\\";

			}
			File f = new File(path);
			f.mkdirs();
			String fileName1 = "temp_buff.txt";
			String fileName2 = "last_r_index.txt";

			sftp.get("temp_buff.txt", path + fileName1);
			sftp.get("last_r_index.txt", path + fileName2);
			File file = new File(path, fileName1);
			File file2 = new File(path, fileName2);
			try {
				InputStream endPoint = new FileInputStream(file2);
				InputStream in = new FileInputStream(file);
				BufferedReader br = new BufferedReader(new InputStreamReader(endPoint));
				String lineTxt = "";
				while ((lineTxt = br.readLine()) != null) {
					itemList.add(lineTxt);
				}
				br.close();
				br = new BufferedReader(new InputStreamReader(in));
				lineTxt = "";
				while ((lineTxt = br.readLine()) != null) {
					itemList.add(lineTxt);
				}
				br.close();
			} catch (Exception e) {
			}
			map.put("endPoint", itemList.get(0));
			itemList.remove(0);
			map.put("list", itemList);
			sb.close();

		} catch (JSchException | SftpException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return map;
	}

}